package model

import (
	"background/db"
	"background/logs"
	"fmt"
	"strings"
	"time"

	"github.com/pkg/errors"
	"qiniupkg.com/x/log.v7"
)

type JSONTime struct {
	time.Time
}

// MarshalJSON 覆盖 time.Time 的 MarshalJSON
func (t JSONTime) MarshalJSON() ([]byte, error) {
	formatted := fmt.Sprintf("\"%s\"", t.Format("2006-01-02 15:04:05"))
	return []byte(formatted), nil
}

type CrawDoc struct {
	Id         int32     `json:"id" gorm:"column:id" sql:"id"`
	Title      string    `json:"title" gorm:"column:title" sql:"title"`
	Type       int32     `json:"type" gorm:"column:type" sql:"type"`
	Content    []byte    `json:"content" gorm:"column:content" sql:"content"`
	Author     string    `json:"author" gorm:"column:author" sql:"author"`
	CreateTime time.Time `json:"create_time" gorm:"column:create_time" sql:"create_time"`
	UpdateTime time.Time `json:"update_time" gorm:"column:update_time" sql:"update_time"`
	DeleteTime time.Time `json:"delete_time" gorm:"column:delete_time" sql:"delete_time"`
	Version    int32     `json:"version" gorm:"column:version" sql:"version"`
	IsPublic   int32     `json:"is_public" gorm:"column:is_public" sql:"is_public"`
	Deleted    int32     `json:"deleted" gorm:"column:deleted" sql:"deleted"`
	OriginUrl  string    `json:"origin_url" gorm:"column:origin_url" sql:"origin_url"`
	EsId       string    `json:"es_id" gorm:"column:es_id" sql:"es_id"`
	DeletedAt  time.Time `json:"deleted_at" gorm:"column:deleted_at" sql:"deleted_at"`
	Father     int32     `json:"father" gorm:"column:father" sql:"father"`
	Level      int32     `json:"level" gorm:"column:level" sql:"level"`
}

type Doc struct {
	ID         int64     `json:"id" gorm:"column:id" sql:"id"`
	Title      string    `json:"title" gorm:"column:title" sql:"title"`
	Type       int32     `json:"type" gorm:"column:type" sql:"type"`
	Content    string    `json:"content" gorm:"column:content" sql:"content"`
	Author     string    `json:"author" gorm:"column:author" sql:"author"`
	CreateTime time.Time `json:"create_time" gorm:"column:create_time" sql:"create_time"`
	UpdateTime time.Time `json:"update_time" gorm:"column:update_time" sql:"update_time"`
	DeleteTime time.Time `json:"delete_time" gorm:"column:delete_time" sql:"delete_time"`
	Version    int32     `json:"version" gorm:"column:version" sql:"version"`
	IsPublic   int32     `json:"is_public" gorm:"column:is_public" sql:"is_public"`
	Deleted    int32     `json:"deleted" gorm:"column:deleted" sql:"deleted"`
	OriginUrl  string    `json:"origin_url" gorm:"column:origin_url" sql:"origin_url"`
	EsId       string    `json:"es_id" gorm:"column:es_id" sql:"es_id"`
	DeletedAt  time.Time `json:"deleted_at" gorm:"column:deleted_at" sql:"deleted_at"`
	Father     int32     `json:"father" gorm:"column:father" sql:"father"`
	Level      int32     `json:"level" gorm:"column:level" sql:"level"`
}

type DocTree struct {
	ID         int64     `json:"id" gorm:"column:id" sql:"id"`
	Title      string    `json:"title" gorm:"column:title" sql:"title"`
	Type       int32     `json:"type" gorm:"column:type" sql:"type"`
	Content    string    `json:"content" gorm:"column:content" sql:"content"`
	Author     string    `json:"author" gorm:"column:author" sql:"author"`
	CreateTime time.Time `json:"create_time" gorm:"column:create_time" sql:"create_time"`
	UpdateTime time.Time `json:"update_time" gorm:"column:update_time" sql:"update_time"`
	DeleteTime time.Time `json:"delete_time" gorm:"column:delete_time" sql:"delete_time"`
	Version    int32     `json:"version" gorm:"column:version" sql:"version"`
	IsPublic   int32     `json:"is_public" gorm:"column:is_public" sql:"is_public"`
	Deleted    int32     `json:"deleted" gorm:"column:deleted" sql:"deleted"`
	OriginUrl  string    `json:"origin_url" gorm:"column:origin_url" sql:"origin_url"`
	EsId       string    `json:"es_id" gorm:"column:es_id" sql:"es_id"`
	DeletedAt  time.Time `json:"deleted_at" gorm:"column:deleted_at" sql:"deleted_at"`
	Father     int32     `json:"father" gorm:"column:father" sql:"father"`
	Level      int32     `json:"level" gorm:"column:level" sql:"level"`
}

// 设置User的表名为`profiles`
func (DocTree) TableName() string {
	return "doc_copy1"
}

// 设置User的表名为`profiles`
func (CrawDoc) TableName() string {
	return "craw_doc"
}

type DocType struct {
	Id       int32  `json:"id" gorm:"column:id" sql:"id"`
	TypeName string `json:"type_name" gorm:"column:type_name" sql:"type_name"`
	Group    int32  `json:"group" gorm:"column:group" sql:"group"`
}
type DocHistory struct {
	ID       int32  `json:"id" gorm:"column:id" sql:"id"`
	Title    string `json:"title" gorm:"column:title" sql:"title"`
	DocId    int32  `json:"doc_id" gorm:"column:doc_id" sql:"doc_id"`
	Content  string `json:"content" gorm:"column:content" sql:"content"`
	EditTime string `json:"edit_time" gorm:"column:edit_time" sql:"edit_time"`
}

type DocGroup struct {
	Int  int32  `sql:"int"`
	Name string `sql:"name"`
}
type ArticleType struct {
	Id        int64  `sql:"id" json:"id"`
	Name      string `sql:"type_name" json:"type_name"`
	Author    string `sql:"author" json:"author"`
	Group     int32  `sql:"group" json:"group"`
	GroupName string `json:"group_name"`
}

func GetArticlesType() []ArticleType {
	ret := []ArticleType{}
	sql := fmt.Sprintf("select * from doc_type")
	e := db.GetMysqlClient().Query2(sql, &ret)
	log.Print(ret)

	for k, _ := range ret {
		group := []DocGroup{}
		sql = fmt.Sprintf("select * from doc_group where doc_group.int = %d", ret[k].Group)
		db.GetMysqlClient().Query2(sql, &group)
		if len(group) > 0 {
			ret[k].GroupName = group[0].Name
		}
	}
	if nil != e {
		logs.Error(e.Error())
		return nil
	}
	return ret
}

/*
CreateDoc 新建文档
*/
func CreateDocTree(doc DocTree) error {
	sql := fmt.Sprintf(`INSERT INTO doc_copy1 ( doc_copy1.title, doc_copy1.content,
		 doc_copy1.author, doc_copy1.type,doc_copy1.is_public,doc_copy1.create_time,father,level) SELECT
			'%s',
			'%s',
			'%s',
			%d ,
			%d,
			'%s',
			%d,
			%d 
			FROM
			DUAL 
			WHERE
	NOT EXISTS ( SELECT * FROM doc_copy1 WHERE doc_copy1.title = '%s' );`, doc.Title, strings.Replace(doc.Content, "'", "\\'", -1),
		doc.Author, doc.Type, doc.IsPublic, time.Now().Format("2006-01-02 15:04:05"), doc.Father, doc.Level, doc.Title)
	_, e := db.GetMysqlClient().Exec(sql)
	log.Print(sql)
	if nil != e {
		log.Print(sql)
		logs.Error(e.Error())
		return e
	}
	return nil
}

/*
CreateDoc 新建文档
*/
func CreateCrawDoc(doc DocTree) error {
	sql := fmt.Sprintf(`INSERT INTO craw_doc ( craw_doc.title, craw_doc.content,
		craw_doc.author, craw_doc.type,craw_doc.is_public,craw_doc.create_time,father,level) SELECT
			'%s',
			'%s',
			'%s',
			%d ,
			%d,
			'%s',
			%d,
			%d 
			FROM
			DUAL 
			WHERE
	NOT EXISTS ( SELECT * FROM craw_doc WHERE craw_doc.title = '%s' );`, doc.Title, strings.Replace(doc.Content, "'", "\\'", -1),
		doc.Author, doc.Type, doc.IsPublic, time.Now().Format("2006-01-02 15:04:05"), doc.Father, doc.Level, doc.Title)
	_, e := db.GetMysqlClient().Query(sql)
	log.Print(sql)
	if nil != e {
		log.Print(sql)
		logs.Error(e.Error())
		return e
	}
	return nil
}
func GetIdFromTitle(title string) int {

	motors := []DocTree{}
	db.GetOrm().LogMode(true)
	db.GetOrm().Model(&DocTree{}).Find(&motors, fmt.Sprintf("title = '%s'", title))
	if len(motors) == 0 {
		return -1
	}
	db.GetOrm().LogMode(false)

	return int(motors[0].ID)

}

/*
	UpdateDoc 更新文档
*/
func UpdateDoc(doc Doc) error {
	sql := fmt.Sprintf(`update doc set doc.author = '%s' ,doc.title = '%s',doc.type = '%d',doc.content = '%s' ,doc.update_time = '%s' ,doc.version = '%d' where doc.id = '%d'; `,
		doc.Author, doc.Title, doc.Type,
		strings.Replace(doc.Content, "'", "\\'", -1), time.Now().Format("2006-01-02 15:04:05"), doc.Version, doc.ID)
	_, e := db.GetMysqlClient().Query(sql)
	if nil != e {
		logs.Error(e.Error())
		return e
	}
	// sql = fmt.Sprintf(`insert into doc_history(title,doc_id,content,edit_time) values('%s',%d,'%s','%s');`,
	// doc.Title,doc.ID,strings.Replace(doc.Content, "'", "\\'", -1), time.Now().Format("2006-01-02 15:04:05"))
	// _, er := db.GetMysqlClient().Query(sql)
	// if nil != er {
	// 	logs.Error(e.Error())
	// 	return e
	// }
	return nil
}

// 添加文件版本。
func InsertDocHistory(doc DocTree) error {
	sql := fmt.Sprintf(`insert into doc_history(title,doc_id,content,edit_time) values('%s',%d,'%s','%s');`,
		doc.Title, doc.ID, strings.Replace(doc.Content, "'", "\\'", -1), time.Now().Format("2006-01-02 15:04:05"))
	_, er := db.GetMysqlClient().Query(sql)
	if nil != er {
		logs.Error(er.Error())
		return er
	}
	return nil
}

/*
	UpdateDoc 更新文档
*/
func UpdateDocTree(doc DocTree) error {
	sql := fmt.Sprintf(`update doc_copy1 set doc_copy1.author = '%s' ,doc_copy1.title = '%s',
		doc_copy1.type = '%d',doc_copy1.content = '%s' ,doc_copy1.update_time = '%s' ,
		doc_copy1.version = '%d' where doc_copy1.id = '%d'; `,
		doc.Author, doc.Title, doc.Type,
		strings.Replace(doc.Content, "'", "\\'", -1), time.Now().Format("2006-01-02 15:04:05"), doc.Version, doc.ID)
	_, e := db.GetMysqlClient().Query(sql)
	if nil != e {
		logs.Error(e.Error())
		return e
	}
	return nil
}

/*
DeleteDoc 删除文档
*/
func DeleteDoc(id int64) error {
	sql := fmt.Sprintf(`delete from doc where id = %d`, id)
	_, e := db.GetMysqlClient().Query(sql)
	if nil != e {
		logs.Error(e.Error())
		return e
	}
	return nil
}

/*
DeleteDoc 删除文档
*/
func DeleteDocTree(id int64) error {
	sql := fmt.Sprintf(`delete from doc_copy1 where id = %d`, id)
	_, e := db.GetMysqlClient().Query(sql)
	if nil != e {
		logs.Error(e.Error())
		return e
	}
	return nil
}

/*
AddArticleType 添加文档类型
*/
func AddArticleType(t ArticleType) error {
	sql := fmt.Sprintf("insert into doc_type(id,type_name,`group`) values ('%d','%s','%d')", t.Id, t.Name, t.Group)
	log.Print(sql)
	_, e := db.GetMysqlClient().Query(sql)
	if nil != e {
		logs.Error(e.Error())
		return e
	}
	return nil
}

/*
UpdateArticleType 更新文档类型
*/
func UpdateArticleType(t ArticleType) error {
	sql := fmt.Sprintf("update  doc_type set  type_name = '%s' and group = '%d' where id = %d", t.Name, t.Group, t.Id)
	_, e := db.GetMysqlClient().Query(sql)
	if nil != e {
		logs.Error(e.Error())
		return e
	}
	return nil

}

/*
DeleteArticleType 删除文档类型
*/
func DeleteArticleType(id int32) error {
	sql := fmt.Sprintf("delete from doc_type where id = '%d'", id)
	_, e := db.GetMysqlClient().Query(sql)
	if nil != e {
		logs.Error(e.Error())
		return e
	}
	return nil

}
func GetAllDocs(tbl string) ([]DocTree, error) {
	ret := []DocTree{}
	sql := fmt.Sprintf("select * from " + tbl)
	e := db.GetMysqlClient().Query2(sql, &ret)
	if nil != e {
		logs.Error(e.Error())
		return nil, e
	}
	return ret, nil
}
func GetAllCraw() ([]DocTree, error) {
	ret := []DocTree{}
	sql := fmt.Sprintf("select * from craw_doc")
	e := db.GetMysqlClient().Query2(sql, &ret)
	if nil != e {
		logs.Error(e.Error())
		return nil, e
	}
	return ret, nil
}
func GetAllGroup() ([]DocGroup, error) {
	ret := []DocGroup{}
	sql := fmt.Sprintf("select * from doc_group")
	e := db.GetMysqlClient().Query2(sql, &ret)
	if nil != e {
		logs.Error(e.Error())
		return nil, e
	}
	return ret, nil
}

func GetTypeGroup(id int32) (DocGroup, error) {
	ret := []DocGroup{}
	sql := fmt.Sprintf("select * from doc_group where doc_group = ?", id)
	e := db.GetMysqlClient().Query2(sql, &ret)
	if nil != e {
		logs.Error(e.Error())
		return DocGroup{}, e
	}
	if len(ret) > 0 {
		return ret[0], nil
	} else {
		return DocGroup{}, errors.New("no existed")
	}
}

func GetGroupTypes(id int32) ([]ArticleType, error) {
	ret := []ArticleType{}
	sql := fmt.Sprintf("select * from doc_type where doc_type.group = %d", id)
	log.Print(sql)
	e := db.GetMysqlClient().Query2(sql, &ret)
	if nil != e {
		logs.Error(e.Error())
		return nil, e
	}
	if len(ret) > 0 {
		return ret, nil
	} else {
		return nil, errors.New("no existed")
	}
}
